import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';

class RoundedRectangleThumbShape extends SliderComponentShape {
  final double height;
  final double width;
  final double radius;
  final Color color;

  const RoundedRectangleThumbShape({
    required this.height,
    required this.width,
    required this.radius,
    required this.color,
  });

  @override
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return Size(width, height);
  }

  @override
  void paint(
    PaintingContext context,
    Offset center, {
    required Animation<double> activationAnimation,
    required Animation<double> enableAnimation,
    required bool isDiscrete,
    required TextPainter labelPainter,
    required RenderBox parentBox,
    required SliderThemeData sliderTheme,
    required TextDirection textDirection,
    required double value,
    required double textScaleFactor,
    required Size sizeWithOverflow,
  }) {
    final Canvas canvas = context.canvas;

    final RRect rrect = RRect.fromRectAndRadius(
      Rect.fromCenter(
        center: center,
        width: width,
        height: height,
      ),
      Radius.circular(radius),
    );

    final Paint paint = Paint()
      ..color = color
      ..style = PaintingStyle.fill;

    canvas.drawRRect(rrect, paint);
  }
}

class LineSliderTickMarkShape extends SliderTickMarkShape {
  const LineSliderTickMarkShape({
    this.width = 2.0,
    this.height = 12.0,
    this.radius = 1.0,
    this.min = 0.0,
    this.max = 1.0,
    this.divisions,
    this.labelStyle,
    this.step = 1.0,
    this.interval = 1,
    this.intervalColor,
  });

  final double width;
  final double height;
  final double radius;
  final double min;
  final double max;
  final int? divisions;
  final TextStyle? labelStyle;
  final double step;
  final int? interval;
  final Color? intervalColor;
  @override
  Size getPreferredSize(
      {required SliderThemeData sliderTheme, required bool isEnabled}) {
    return Size(width, height);
  }

  @override
  void paint(
    PaintingContext context,
    Offset center, {
    required RenderBox parentBox,
    required SliderThemeData sliderTheme,
    required Animation<double> enableAnimation,
    required TextDirection textDirection,
    required Offset thumbCenter,
    required bool isEnabled,
  }) {
    final double xOffset = center.dx - thumbCenter.dx;
    final (Color? begin, Color? end) = switch (textDirection) {
      TextDirection.ltr when xOffset > 0 => (
          sliderTheme.disabledInactiveTickMarkColor,
          sliderTheme.inactiveTickMarkColor,
        ),
      TextDirection.rtl when xOffset < 0 => (
          sliderTheme.disabledInactiveTickMarkColor,
          sliderTheme.inactiveTickMarkColor,
        ),
      TextDirection.ltr || TextDirection.rtl => (
          sliderTheme.disabledActiveTickMarkColor,
          sliderTheme.activeTickMarkColor,
        ),
    };

    // 计算当前刻度值
    final double totalWidth = parentBox.size.width;
    final double normalizedX = center.dx / totalWidth;
    final double value = min + (max - min) * normalizedX;
    final double roundedValue = (value / step).round() * step;

    // 计算是否需要显示当前刻度的标签
    final bool shouldShowLabel = interval != null &&
        (roundedValue == min || // 显示最小值
            roundedValue == max || // 显示最大值
            (roundedValue % interval!).abs() < 0.001); // 在interval间隔点显示

    // 根据是否是主要刻度选择颜色和高度
    final Paint paint = Paint()
      ..color = shouldShowLabel && intervalColor != null
          ? intervalColor! // 使用intervalColor作为主要刻度的颜色
          : ColorTween(begin: begin, end: end).evaluate(enableAnimation)!;

    // 绘制刻度线
    final double lineHeight = shouldShowLabel ? height : height / 2; // 主要刻度线更长
    final Offset offsetBottom = Offset(center.dx, center.dy + lineHeight / 2);

    final RRect rrect = RRect.fromRectAndRadius(
      Rect.fromCenter(
        center: shouldShowLabel ? center : offsetBottom,
        width: width,
        height: lineHeight,
      ),
      Radius.circular(radius),
    );
    context.canvas.drawRRect(rrect, paint);

    // 只在需要显示的刻度处绘制文本标签
    if (shouldShowLabel) {
      final TextPainter textPainter = TextPainter(
        text: TextSpan(
          text: roundedValue.toInt().toString(),
          style: labelStyle,
        ),
        textAlign: TextAlign.center,
        textDirection: TextDirection.ltr,
      );

      textPainter.layout();
      textPainter.paint(
        context.canvas,
        Offset(
          center.dx - textPainter.width / 2,
          center.dy + height / 1.5,
        ),
      );
    }
  }
}

class MSSlider extends StatefulWidget {
  const MSSlider({
    super.key,
    this.min = 0.0,
    this.max = 1.0,
    this.value = 0,
    this.step = 0.1,
    this.onChanged,
    this.unit = '',
    this.interval = 1,
  });

  final double min;
  final double max;
  final double value;
  final double step;
  final String unit;
  final ValueChanged<double>? onChanged;

  /// 文本显示间隔
  final int interval;
  @override
  State<MSSlider> createState() => _MSSliderState();
}

class _MSSliderState extends State<MSSlider> {
  double _value = 0;
  int? _divisions;
  Timer? _debounceTimer;

  @override
  void initState() {
    super.initState();
    _value = widget.value < widget.min ? widget.min : widget.value;
    _divisions = ((widget.max - widget.min) / widget.step).round();
    setState(() {});
  }

  @override
  void didUpdateWidget(MSSlider oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.value != widget.value) {
      setState(() {
        _value = widget.value;
      });
    }
  }

  @override
  void dispose() {
    _debounceTimer?.cancel();
    super.dispose();
  }

  void _onChanged(double value) {
    final roundedValue = (value / widget.step).round() * widget.step;
    setState(() {
      _value = roundedValue;
    });

    _debounceTimer?.cancel();
    _debounceTimer = Timer(300.milliseconds, () {
      widget.onChanged?.call(roundedValue);
    });
  }

  @override
  Widget build(BuildContext context) {
    return SliderTheme(
      data: context.theme.sliderTheme.copyWith(
        thumbShape: RoundedRectangleThumbShape(
          height: 24.h,
          width: 4.w,
          radius: 4.r,
          color: context.theme.colorScheme.primaryFixed,
        ),
        tickMarkShape: LineSliderTickMarkShape(
          width: 2.w,
          height: 24.h,
          radius: 2.r,
          min: widget.min,
          max: widget.max,
          divisions: _divisions,
          interval: widget.interval,
          step: widget.step,
          intervalColor: context.theme.colorScheme.tertiary,
          labelStyle: context.theme.textTheme.bodyMedium?.copyWith(
            color: context.theme.colorScheme.tertiary,
          ),
        ),
        inactiveTickMarkColor: context.theme.colorScheme.outline,
        activeTickMarkColor: context.theme.colorScheme.outline,
        activeTrackColor: Colors.transparent,
        inactiveTrackColor: Colors.transparent,
        overlayColor: Colors.transparent,
      ),
      child: Column(
        children: [
          Text.rich(
            TextSpan(
              text: _value.toStringAsFixed(0),
              children: [
                WidgetSpan(child: SizedBox(width: 4.w)),
                TextSpan(
                  text: widget.unit,
                  style: context.theme.textTheme.bodyMedium?.copyWith(
                    color: context.theme.colorScheme.primary,
                  ),
                ),
              ],
            ),
            style: context.theme.textTheme.displayMedium?.copyWith(
              color: context.theme.colorScheme.primary,
            ),
          ),
          Slider(
            padding: EdgeInsets.all(20.w).copyWith(top: 8.h),
            value: _value,
            min: widget.min,
            max: widget.max,
            divisions: _divisions,
            onChanged: _onChanged,
          ),
        ],
      ),
    );
  }
}
